﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using ExcellOnServices.Models;
using PagedList;
using ExcellOnServices.Models.Utils;

namespace ExcellOnServices.Areas.DashBoard.Controllers
{
    public class ProductsController : Controller
    {
        private ExcellOnServicesContext db = new ExcellOnServicesContext();

        // GET: /DashBoard/Products/
        [Authorize]
		public ActionResult Index(string search, string sortBy, bool sortAsce = true, int? category = null, int page = 1) {
            int id = int.Parse(User.Identity.Name);
            var products = db.Products.Where(p => p.Company_Id == id).Include(p => p.Accounts_Company).Include(p => p.Category);

			if (!String.IsNullOrEmpty(search)) {
                products = products.Where(p => p.Name.ToUpper().Contains(search.ToUpper()));
            }

			if (category != null) {
                products = products.Where(p => p.Category_Id == category);
            }

			switch (sortBy) {
                case "brandname":
					if (!sortAsce) {
                        products = products.OrderByDescending(p => p.Accounts_Company.BrandName);
					} else {
                        products = products.OrderBy(p => p.Accounts_Company.BrandName);
                    }
                    break;
                case "category":
					if (!sortAsce) {
                        products = products.OrderByDescending(p => p.Category.Name);
					} else {
                        products = products.OrderBy(p => p.Category.Name);
                    }
                    break;
                case "name":
					if (!sortAsce) {
                        products = products.OrderByDescending(p => p.Name);
					} else {
                        products = products.OrderBy(p => p.Name);
                    }
                    break;
                case "price":
					if (!sortAsce) {
                        products = products.OrderByDescending(p => p.Price);
					} else {
                        products = products.OrderBy(p => p.Price);
                    }
                    break;
                case "discount":
					if (!sortAsce) {
                        products = products.OrderByDescending(p => p.Discount);
					} else {
                        products = products.OrderBy(p => p.Discount);
                    }
                    break;
                case "publish":
					if (!sortAsce) {
                        products = products.OrderByDescending(p => p.Published);
					} else {
                        products = products.OrderBy(p => p.Published);
                    }
                    break;
                default:
                    products = products.OrderByDescending(p => p.Id);
                    break;
            }

            ViewBag.SortBy = sortBy;
            ViewBag.SortOrder = sortAsce;
            ViewBag.CategoryId = category;
            ViewBag.SearchString = search;
            ViewBag.Page = page;
            ViewBag.Category = new SelectList(db.Categories.ToList(), "Id", "Name");
            return View(products.ToPagedList(page, 4));
        }

        // GET: /DashBoard/Products/Details/5
        [Authorize]
		public ActionResult Details(int? id) {
			if (id == null) {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.Products.Find(id);
			if (product == null) {
                return HttpNotFound();
            }
            return View(product);
        }

        // GET: /DashBoard/Products/Create
        [Authorize]
		public ActionResult Create() {
            ViewBag.CatId = new SelectList(db.Categories, "Id", "Name", null);
            return View();
        }

        // POST: /DashBoard/Products/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize]
		public ActionResult Create([Bind(Include = "Name,ImageUrl,Price,Discount,Description,Category_Id")] Product product, HttpPostedFileBase ImageUrl, bool isDirectCreate = false) {
			try {
				if (ModelState.IsValid) {
					if (ImageUrl != null && ImageUrl.ContentLength > 0) {
                        string path = String.Empty;
                        string fileName = UniqueFileNames.GetUniqueFileName(System.IO.Path.GetFileName(ImageUrl.FileName));

						switch (product.Category_Id) {
                            case 1:
                                path += "books_magazines/";
                                break;
                            case 2:
                                path += "movies_music_games/";
                                break;
                            case 3:
                                path += "electronics_computers/";
                                break;
                            case 4:
                                path += "clothing_shoes_jewelry/";
                                break;
                            case 5:
                                path += "toys_kids_baby/";
                                break;
                            case 6:
                                path += "home_garden_tools/";
                                break;
                        }

                        product.ImageUrl = "/Resources/products/" + path + fileName;

                        string pathTemp = product.ImageUrl.Replace("/", "\\");
                        pathTemp = pathTemp.Remove(0, 1);
                        path = System.IO.Path.Combine(Server.MapPath("~/"), pathTemp);

                        ImageUrl.SaveAs(path);
                    }
                    product.Published = false;
                    product.Company_Id = int.Parse(@User.Identity.Name);

                    db.Products.Add(product);
                    db.SaveChanges();
					if (!isDirectCreate) {
                        return RedirectToAction("Index");
					} else {
                        return RedirectToAction("Create", "Orders");
                    }
                }
			} catch (DataException ex) {
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator." + ex.Message);
            }
            ViewBag.CatId = new SelectList(db.Categories, "Id", "Name", product.Category_Id);
            return View(product);
        }

        // GET: /DashBoard/Products/Edit/5
        [Authorize]
		public ActionResult Edit(int? id) {
			if (id == null) {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.Products.Find(id);
			if (product == null) {
                return HttpNotFound();
            }
            ViewBag.CatId = new SelectList(db.Categories, "Id", "Name", product.Category_Id);
            return View(product);
        }

        // POST: /DashBoard/Products/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize]
        public ActionResult Edit([Bind(Include = "Id,Name,ImageUrl,Price,Discount,Description,Category_Id")] Product product, HttpPostedFileBase ImageUrl)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    if (ImageUrl != null && ImageUrl.ContentLength > 0)
                    {
                        string path = String.Empty;
                        string fileName = UniqueFileNames.GetUniqueFileName(System.IO.Path.GetFileName(ImageUrl.FileName));

						switch (product.Category_Id) {
                            case 1:
                                path += "books_magazines/";
                                break;
                            case 2:
                                path += "movies_music_games/";
                                break;
                            case 3:
                                path += "electronics_computers/";
                                break;
                            case 4:
                                path += "clothing_shoes_jewelry/";
                                break;
                            case 5:
                                path += "toys_kids_baby/";
                                break;
                            case 6:
                                path += "home_garden_tools/";
                                break;
                        }

                        product.ImageUrl = "/Resources/products/" + path + fileName;

                        string pathTemp = product.ImageUrl.Replace("/", "\\");
                        pathTemp = pathTemp.Remove(0, 1);
                        path = System.IO.Path.Combine(Server.MapPath("~/"), pathTemp);

                        ImageUrl.SaveAs(path);
                    }
                    product.Company_Id = int.Parse(User.Identity.Name);
                    db.Entry(product).State = EntityState.Modified;
                    db.SaveChanges();

                    return RedirectToAction("Index");
                }
			} catch (DataException ex) {
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator." + ex.Message);
            }
            ViewBag.CatId = new SelectList(db.Categories, "Id", "Name", product.Category_Id);
            return View(product);
        }

        // POST: /DashBoard/Products/Delete/5
        [Authorize]
        [ActionName("Delete")]
		public ActionResult Delete(int? id, string search, string sortBy = "price", bool sortAsce = true, int? category = null, int page = 1) {
			if (id == null) {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.Products.Find(id);
            db.Products.Remove(product);
            db.SaveChanges();
            return RedirectToAction("Index", new { search = search, sortBy = sortBy, sortAsce = sortAsce, category = category, page = page });
        }

		protected override void Dispose(bool disposing) {
			if (disposing) {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
